'use client';

import { type ReactNode, useEffect, useState } from 'react';
import classNames from 'classnames';
import type { IPostFollowsMessage } from '@/interfaces';
import { useMutation, useQuery } from '@tanstack/react-query';
import useToast from '@/hooks/useToast';
import {
  postCancelFollow,
  postFollowRead,
  queryPostFollowMessage,
  removeFollow,
} from '@/services/api';
import { toRelativeTime } from '@/lib/tool';
import Nodata from '@/app/[locale]/common/nodata/nodata';
import Link from 'next/link';
import type { IFollowPageContext } from '@/contexts/follow';

export default function FollowPage(
  this: any,
  { source, translatedFields }: IFollowPageContext,
) {
  const { show } = useToast();
  const [currentReadFollowMessageId, setCurrentReadFollowMessageId] =
    useState<number>();
  const [currentRemoveFollowMessageId, setCurrentRemoveFollowMessageId] =
    useState<number>();
  const [pages, setPages] = useState<IPostFollowsMessage[]>(source.messages);

  const queryPostFollowMessageQuery = useQuery(
    ['/forum', '/posts', '/follows', '/message', 'page'],
    async () => {
      return (await queryPostFollowMessage()) as IPostFollowsMessage[];
    },
    {
      enabled: !!source.path.user,
      initialData: source.messages,
    },
  );

  const postFollowReadMutation = useMutation(postFollowRead);
  const cancelFollowMutation = useMutation(postCancelFollow);
  const removeFollowMutation = useMutation(removeFollow);

  useEffect(() => {
    if (queryPostFollowMessageQuery.data) {
      setPages(
        queryPostFollowMessageQuery.data.map((item) => {
          item._contentUpdatedOn = toRelativeTime(item.contentUpdatedOn);
          return item;
        }),
      );
    }
  }, [queryPostFollowMessageQuery.data]);

  async function onClickCancel(item: IPostFollowsMessage, index: number) {
    try {
      setCurrentRemoveFollowMessageId(item.id);

      await Promise.all([
        cancelFollowMutation.mutateAsync({ id: item.postId + '' }),
        removeFollowMutation.mutateAsync({
          id: item.postId + '',
        }),
      ]);

      setPages((prevState) => {
        prevState.splice(index, 1);
        return prevState;
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.unfollowCompleted,
      });
    } catch (e) {
      cancelFollowMutation.reset();
      removeFollowMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setCurrentRemoveFollowMessageId(undefined);
    }
  }

  async function onClickRead(item: IPostFollowsMessage) {
    try {
      setCurrentReadFollowMessageId(item.id);

      await postFollowReadMutation.mutateAsync({
        id: item.id + '',
      });
      await queryPostFollowMessageQuery.refetch({ throwOnError: true });

      show({
        type: 'SUCCESS',
        message: translatedFields.readCompleted,
      });
    } catch (e) {
      postFollowReadMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setCurrentReadFollowMessageId(undefined);
    }
  }

  if (pages.length > 0) {
    return (
      <div className="col px-2 py-4">
        <div className="card border-0">
          <div className="card-body container">
            {pages.map((item, index) => {
              return (
                <div
                  key={item.id}
                  className="row z-1"
                  style={{ marginBottom: -2 }}
                >
                  <div className="col-auto px-0 mx-0">
                    <div className="d-flex flex-column align-items-center h-100">
                      <Circle className="">
                        <Circle width={32} height={32} className="">
                          <i className="bi bi-bell-fill fs-5 text-primary"></i>
                        </Circle>
                      </Circle>
                      <Line className="" />
                    </div>
                  </div>
                  <div className="col-auto px-0 mx-0">
                    <Line reverse className="" />
                  </div>
                  <div className="col p-2 pb-3">
                    <div className="card border-0">
                      <div className="card-body vstack gap-4">
                        <h5 className="card-title">
                          <Link
                            className="link-body-emphasis link-offset-3 link-underline-opacity-0 link-underline-opacity-100-hover"
                            href={`/posts/${item.postId}`}
                          >
                            {item.name}
                          </Link>
                        </h5>
                        <div>
                          <Link
                            className="btn btn-primary"
                            href={`/posts/${item.postId}`}
                          >
                            <i className="bi bi-book me-2"></i>
                            {translatedFields.readMore}
                          </Link>
                        </div>
                      </div>
                      <div className="card-footer border-0">
                        <div className="d-flex align-items-center justify-content-between">
                          <div>{item._contentUpdatedOn}</div>
                          <div className="hstack gap-2">
                            <button
                              disabled={
                                currentRemoveFollowMessageId === item.id
                              }
                              onClick={onClickCancel.bind(this, item, index)}
                              type="button"
                              className="btn focus-ring focus-ring-danger text-danger btn-sm"
                            >
                              {currentRemoveFollowMessageId === item.id && (
                                <span
                                  className="spinner-border spinner-border-sm me-2"
                                  role="status"
                                  aria-hidden="true"
                                ></span>
                              )}
                              {translatedFields.unfollow}
                            </button>

                            <button
                              disabled={currentReadFollowMessageId === item.id}
                              onClick={onClickRead.bind(this, item)}
                              type="button"
                              className="btn focus-ring focus-ring-primary text-primary btn-sm"
                            >
                              {currentReadFollowMessageId === item.id && (
                                <span
                                  className="spinner-border spinner-border-sm me-2"
                                  role="status"
                                  aria-hidden="true"
                                ></span>
                              )}
                              {translatedFields.alreadyRead}
                            </button>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="col px-2 py-4">
      <div className="container-fluid">
        <Nodata />
      </div>
    </div>
  );
}

const Circle = ({
  width,
  height,
  children,
  className,
}: {
  width?: number;
  height?: number;
  children?: ReactNode;
  className?: string;
}) => {
  return (
    <div
      className={classNames(
        'rounded-circle border d-flex align-items-center justify-content-center flex-shrink-0',
        className,
      )}
      style={{ width: width ?? 48, height: height ?? 48 }}
    >
      {children && children}
    </div>
  );
};

const Line = ({
  width,
  height,
  className,
  reverse,
}: {
  width?: number;
  height?: number;
  className?: string;
  reverse?: boolean;
}) => {
  return (
    <div
      className={classNames(
        'border',
        className,
        reverse
          ? 'w-100 border-top border-bottom border-start-0 border-end-0'
          : 'h-100 border-start border-end border-top-0 border-bottom-0',
      )}
      style={
        reverse
          ? {
              width: width && width > 0 ? width + 2 : '12px !important',
              height: height ?? 10,
              marginLeft: -2,
              marginTop: '1.2rem',
            }
          : {
              width: width ?? 10,
              marginTop: -2,
            }
      }
    ></div>
  );
};
